home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
526-550
/
disk_540
/
browser
/
browserii_src.lzh
/
ActionBack.c
next >
Wrap
C/C++ Source or Header
|
1991-07-12
|
10KB
|
340 lines
/*
* ActionBack.c - Copyright © 1991 by S.R. & P.C.
*
* Created: 21 Apr 1991 16:09:52
* Modified: 12 Jul 1991 20:43:07
*
* Make>> make
*/
#include "Global.h"
#include "FileList.h"
#include "ActionBack.h"
#include "Process.h"
#include "proto/ActionBack.h"
#include "proto/Process.h"
#include "proto/Windows.h"
#include "proto/Mouse.h"
#include "proto/Scan.h"
#include "proto/Sort.h"
#include "proto/Draw.h"
#include "proto/String.h"
#include "proto/File.h"
#include "proto/FileList.h"
extern struct ExecBase *SysBase;
extern struct MinList WindowList;
extern struct Config Config;
extern struct MsgPort *ProcessPort;
#define AB_DELETE (AB_DELETE_DEST|AB_DELETE_SOURCE)
/* Search by name a ScrollEntry in a window */
static struct ScrollEntry *FindEntry(struct BrowserWindow *Win, char *Name)
{
struct ScrollEntry *S;
short i;
/* No list for main window, only an array */
if (Win->bw_Type == BW_MAIN) {
for( i=0 ; i < Win->bw_ShownEntries ; i++ ) {
S = Win->bw_EntryArray[i];
if (!Strcmp(S->se_FileInfo.fi_Name, Name))
return (S->se_State & STATE_DELETED) ? NULL : S;
}
}
else {
S = (struct ScrollEntry *)Win->bw_EntryList.mlh_Head;
while(S->se_Node.mln_Succ) {
if (!Strcmp(S->se_FileInfo.fi_Name, Name))
return (S->se_State & STATE_DELETED) ? NULL : S;
S = (struct ScrollEntry *)S->se_Node.mln_Succ;
}
}
return NULL;
}
/* Search by name a ScrollEntry in NewEntryList of a window */
static struct ScrollEntry *FindNewEntry(struct BrowserWindow *Win, char *Name)
{
struct ScrollEntry *S;
S = (struct ScrollEntry *)Win->bw_NewEntryList.mlh_Head;
while(S->se_Node.mln_Succ) {
if (!Strcmp(S->se_FileInfo.fi_Name, Name))
return S;
S = (struct ScrollEntry *)S->se_Node.mln_Succ;
}
return NULL;
}
static void ActionBack(struct SuperFileInfo *sfi, BPTR DirLock, short Action)
{
struct BrowserWindow *Win;
struct ScrollEntry *S = NULL;
struct Point Position;
BOOL PrintString = FALSE;
short len;
if (!Action)
return;
if (Action & AB_SCANDEVS) {
ScanDevs();
return;
}
switch(sfi->FileInfo.fi_Type) {
case DLX_FILE:
case DLX_DIR:
Win = FindDir(DirLock);
break;
default: /* device, volume, assign */
Win = (struct BrowserWindow *)WindowList.mlh_Head;
}
if (Win) {
if (Action & AB_NEW_ENTRY) {
if (S = FindEntry(Win, sfi->FileInfo.fi_Name)) {
/* size of new entry may be different, so... */
Win->bw_NumBytes -= S->se_FileInfo.fi_Size;
Win->bw_NumBlocks -= S->se_FileInfo.fi_NumBlocks;
Win->bw_NumBytes += sfi->FileInfo.fi_Size;
Win->bw_NumBlocks += sfi->FileInfo.fi_NumBlocks;
if (S->se_Print) {
Win->bw_ShownBytes -= S->se_FileInfo.fi_Size;
Win->bw_ShownBlocks -= S->se_FileInfo.fi_NumBlocks;
Win->bw_ShownBytes += sfi->FileInfo.fi_Size;
Win->bw_ShownBlocks += sfi->FileInfo.fi_NumBlocks;
CopyFileInfo(&S->se_FileInfo, &sfi->FileInfo);
if ((len = strlen(S->se_FileInfo.fi_Name)) > Win->bw_MaxFilenameLen) {
Win->bw_Flags |= BWF_REBUILD_STRINGS;
Win->bw_NewMaxFilenameLen = MAX(len, Win->bw_NewMaxFilenameLen);
}
else {
BuildPrintString(Win, S);
PrintString = TRUE;
}
}
else
CopyFileInfo(&S->se_FileInfo, &sfi->FileInfo);
MakeBottomInfoString(Win);
RefreshBottomInfo(Win);
}
else if (S = FindNewEntry(Win, sfi->FileInfo.fi_Name)) {
CopyFileInfo(&S->se_FileInfo, &sfi->FileInfo);
}
else if (S = AllocMem(sizeof(struct ScrollEntry), MEMF_PUBLIC|MEMF_CLEAR)) {
CopyFileInfo(&S->se_FileInfo, &sfi->FileInfo);
/* entry can only be a file or dir here, so set pen to 1 or 3 */
S->se_Pen = (S->se_FileInfo.fi_Type == DLX_FILE) ? 1 : 3;
AddTail((struct List *)&Win->bw_NewEntryList, (struct Node *)S);
Win->bw_NumNewEntries++;
Win->bw_Flags |= BWF_REBUILD_ARRAY;
if ((len = strlen(S->se_FileInfo.fi_Name)) > Win->bw_MaxFilenameLen) {
Win->bw_Flags |= BWF_REBUILD_STRINGS;
Win->bw_NewMaxFilenameLen = MAX(len, Win->bw_NewMaxFilenameLen);
}
}
}
else if (S = FindEntry(Win, sfi->OldName)) {
if (Action & AB_DELETE) {
if (S->se_State & STATE_SELECTED)
DoSelect(Win, S, OPT_TOGGLESELECT); /* deselect entry */
S->se_State = STATE_DELETED;
Win->bw_NumDeleted++;
Win->bw_Flags |= BWF_REBUILD_ARRAY;
/* if this file had the longest filename, tell DoUpdateDir() to check if
* strings could be made smaller */
if (strlen(sfi->OldName) == Win->bw_MaxFilenameLen)
Win->bw_Flags |= BWF_CHECK_MAXLEN;
PrintString = TRUE;
}
if (S->se_State & STATE_GHOSTED) { /* change state only if ghosted */
S->se_State &= ~STATE_GHOSTED;
if (S->se_Print) {
if (Action & AB_SELECT)
DoSelect(Win, S, 0);
PrintString = TRUE;
}
}
if (S->se_Print) {
if (Action & AB_UPDATE_STRING) {
CopyFileInfo(&S->se_FileInfo, &sfi->FileInfo);
BuildPrintString(Win, S);
PrintString = TRUE;
}
if (Action & AB_RENAME_ENTRY) {
CopyFileInfo(&S->se_FileInfo, &sfi->FileInfo);
Win->bw_Flags |= BWF_SORT;
if ((len = strlen(S->se_FileInfo.fi_Name)) > Win->bw_MaxFilenameLen) {
Win->bw_Flags |= BWF_REBUILD_STRINGS;
Win->bw_NewMaxFilenameLen = MAX(len, Win->bw_NewMaxFilenameLen);
}
else {
/* if this file had the longest filename, tell DoUpdateDir() to check if
* strings could be made smaller */
if (strlen(sfi->OldName) == Win->bw_MaxFilenameLen && len <Win->bw_MaxFilenameLen)
Win->bw_Flags |= BWF_CHECK_MAXLEN;
BuildPrintString(Win, S);
PrintString = TRUE;
}
}
/* Modified entry may no more pass through filters so check it */
if (!MatchFilters(&S->se_FileInfo, &Win->bw_FiltersInfo))
Win->bw_Flags |= BWF_REBUILD_ARRAY|BWF_REBUILD_STRINGS;
}
}
else if (S = FindNewEntry(Win, sfi->OldName)) {
if (Action & AB_DELETE) {
Remove((struct Node *)S);
Win->bw_NumNewEntries--;
}
else
CopyFileInfo(&S->se_FileInfo, &sfi->FileInfo);
}
if (PrintString && GetSePosition(Win, S, &Position))
Print(Win, S, Position.X, Position.Y);
}
}
void DoActionBack(struct SuperFileInfo *sfi, BPTR SrcDir, BPTR DestDir)
{
if (sfi->ActionBack == AB_NONE)
return;
if (DestDir)
ActionBack(sfi, DestDir, sfi->ActionBack & AB_DEST_FLAGS);
/* Don't check SrcDir, it may be the main window */
ActionBack(sfi, SrcDir, sfi->ActionBack & AB_SOURCE_FLAGS);
}
void SendActionBack(struct SuperFileInfo *sfi, BPTR SrcDir, BPTR DestDir)
{
struct TaskData *TaskData;
struct BrowserMsg *Msg;
if (sfi->ActionBack == AB_NONE)
return;
if (Config.Options & OPT_ASYNCHRONOUS) {
TaskData = (struct TaskData *)SysBase->ThisTask->tc_UserData;
FreeProcessRepliedMsg(TaskData);
if (!(Msg = AllocBrowserMsg()))
return;
Msg->bm_ExecMessage.mn_ReplyPort = TaskData->td_ReplyPort;
Msg->bm_Type = BM_ACTIONBACK;
Msg->bm_Info.ActionBack.SrcDir = SrcDir;
Msg->bm_Info.ActionBack.DestDir = DestDir;
/* Copy SuperFileInfo */
Msg->bm_Info.ActionBack.sfi = *sfi;
if (sfi->FileInfo.fi_Comment)
Msg->bm_Info.ActionBack.sfi.FileInfo.fi_Comment = CopyStr(sfi->FileInfo.fi_Comment);
PutMsg(ProcessPort, (struct Message *)Msg);
TaskData->td_MsgCount++;
}
else
DoActionBack(sfi, SrcDir, DestDir);
sfi->ActionBack = AB_NONE;
}
void DoUpdateDir(BPTR Dir)
{
struct BrowserWindow *Win;
struct ScrollEntry *S, *Next;
short len=0, i;
BOOL Ok = TRUE;
UBYTE Flags;
if (Win = FindDir(Dir)) {
if (Flags = Win->bw_Flags) {
/* if strings have to be rebuilt, they must be longer, so don't check if
* they can be made smaller !! */
if ((Flags & BWF_CHECK_MAXLEN) && !(Flags & BWF_REBUILD_STRINGS)) {
for( i=0 ; i<Win->bw_ShownEntries ; i++ ) {
S = Win->bw_EntryArray[i];
if (!(S->se_State & STATE_DELETED))
len = MAX(len, strlen(S->se_FileInfo.fi_Name));
}
if (len < Win->bw_MaxFilenameLen) {
Win->bw_MaxFilenameLen = len;
Flags |= BWF_REBUILD_STRINGS;
}
}
if ((Flags & BWF_SORT) && !(Flags & BWF_REBUILD_ARRAY) && (Win->bw_Sort & 0x0F) == NAME_SORT)
Sort(Win);
if ((Flags & BWF_REBUILD_STRINGS) && !(Flags & BWF_REBUILD_ARRAY)) {
Ok = BuildPrintStrings(Win);
}
else if ((Flags & BWF_REBUILD_ARRAY) && !(Flags & BWF_REBUILD_STRINGS)) {
if (Ok = UpdateEntryList(Win, TRUE)) {
Win->bw_ShownFiles = Win->bw_ShownDirs = Win->bw_ShownEntries = 0;
Win->bw_ShownBytes = Win->bw_ShownBlocks = 0;
S = (struct ScrollEntry *)Win->bw_EntryList.mlh_Head;
i = 0;
while(Next = (struct ScrollEntry *)S->se_Node.mln_Succ) {
if (S->se_Print) {
Win->bw_EntryArray[i++] = S;
if (S->se_FileInfo.fi_Type == DLX_FILE)
Win->bw_ShownFiles++;
else
Win->bw_ShownDirs++;
Win->bw_ShownBytes += S->se_FileInfo.fi_Size;
Win->bw_ShownBlocks += S->se_FileInfo.fi_NumBlocks;
}
S = Next;
}
Win->bw_ShownEntries = i;
Sort(Win);
MakeBottomInfoString(Win);
}
}
else { /* both flags BWF_REBUILD_ARRAY and BWF_REBUILD_STRINGS are set */
if (Ok = List2Array(Win))
MakeBottomInfoString(Win);
}
Win->bw_Flags = 0;
if (Ok)
RefreshWindow(Win);
else
CloseBrowserWindow(Win);
}
else { /* some entries may have been reselected, so update bottom info */
MakeBottomInfoString(Win);
RefreshBottomInfo(Win);
}
}
}
void SendUpdateDir(BPTR Dir)
{
struct TaskData *TaskData;
struct BrowserMsg *Msg;
if (!Dir)
return;
if (Config.Options & OPT_ASYNCHRONOUS) {
TaskData = (struct TaskData *)SysBase->ThisTask->tc_UserData;
if (!(Msg = AllocBrowserMsg()))
return;
Msg->bm_ExecMessage.mn_ReplyPort = TaskData->td_ReplyPort;
Msg->bm_Type = BM_UPDATEDIR;
Msg->bm_Info.Dir = Dir;
PutMsg(ProcessPort, (struct Message *)Msg);
TaskData->td_MsgCount++;
/* Wait for all pending messages before unlocking Dir, or locks given to
* actionback messages won't be valid anymore */
WaitAllMsg(TaskData);
}
else
DoUpdateDir(Dir);
}